#include <stdio.h>
#include <string.h>
#include "person.h"
#include "student.h"
#include "student_imp.h"

static void _V_Say(ObjectPtr obj, const char* text) {
    Student *p = (Student*)obj;
    printf("%s | name is %s, age: %d, grade: %d\n",
           text, p->data.s._name, p->data.s._age, p->data._grade);
}

static void _V_WorkForYear(ObjectPtr obj) {
    Student *p = (Student*)obj;
    p->data.s._age ++;
    p->data._grade ++;
    printf("I am upgrade now! grade:%d\n", p->data._grade);
}

void Student_VFuncInit(Student_Func *vfunc) {
    Person_VFuncInit((Person_Func*)vfunc);
    vfunc->s._Say = _V_Say;
    vfunc->s._WorkForYear = _V_WorkForYear;
}

#define PARAM_LIST      PARAM_LIST_2
#define TYPE_PARAM_LIST C_TYPE_PARAM_LIST_2(const char*, int)
BASE_FUNC_DEFINE(Student, Person, OOP);
#undef TYPE_PARAM_LIST
#undef PARAM_LIST

void Student_Construct(ObjectPtr obj, const char* name, int age) {
    OOP_ASSERT(is_instance_of(obj, ClassID_Student));
    Person_Construct(obj, name, age);

    Student_Data *data = (Student_Data*)(obj+1);
    data->_grade = 1;
}

void Student_Destruct(ObjectPtr obj) {
    OOP_ASSERT(is_instance_of(obj, ClassID_Student));

    //! TODO:
    Person_Destruct(obj);
}

void Student_SetGrade(ObjectPtr obj, int grade) {
    if (grade > 0) {
        OOP_ASSERT(is_instance_of(obj, ClassID_Student));

        Student_Data *data = (Student_Data*)(obj+1);
        data->_grade = grade;
    }
}


